﻿#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;

void Test1()
{
	//反向迭代器reverse_iterator
	string s1("abcdefghijk");
	string::reverse_iterator rit = s1.rbegin();
	for (; rit != s1.rend(); ++rit)
	{
		cout << (*rit)++ << ' ';
	}
	cout << endl;
	auto rit2 = s1.rbegin();
	while (rit2 != s1.rend())
	{
		cout << *rit2 << ' ';
		++rit2;
	}
	cout << endl<< s1.max_size() << endl;
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;

	//提前扩容
	s1.reserve(30);
	cout << s1.capacity() << endl;

	//清空字符串
	s1.clear();
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;

	//缩容到最小
	s1.shrink_to_fit();
	cout << s1.capacity() << endl;

	//设置有效字符的个数，用'1'初始化，默认用0=='\0'
	s1.resize(10, '1');
	cout << s1 << " " << s1.size() << endl;
	cout << s1.capacity() << endl;

	//运算符重载
	s1 = "abcdefg";

	//at()类似[]
	cout << s1.at(0) << endl;

	//尾插1个'h'……
	cout << s1.append(1, 'h') << ' ' << s1.append("ijklmn") << endl;

	//只能尾插一个字符，无返回值
	s1.push_back('o');

	//运算符重载
	s1 += "pq";
	
	//不建议在同一个语句通过流插入/提取对字符串两次操作（第2个操作会在不影响/修改第1个操作结果下进行）
	//整体覆盖
	cout << s1.assign(2, '2') << s1.assign("aaaaa") << endl;
	cout << s1.size() << endl;
	s1 = "abcdefghijk";

	//在下标0插入1个'0'
	cout << s1.insert(0, 1, '0') << endl;
	cout << s1.insert(1, "123") << endl;

	//从下标0开始删3个字符
	cout << s1.erase(0, 3) << endl;

	//将原字符串从下标0开始的1个字符替换成2个'2'
	cout << s1.replace(0, 1, 2, '2') << endl;
	cout << s1.replace(0, 2, "33") << endl;

	//找"33"，从0及其后开始
	cout << s1.find("33", 0) << endl;//默认从0

	// 获取file的后缀
	string file("string.cpp");
	size_t pos = file.rfind('.');//默认从最后往前找
	string suffix(file.substr(pos, file.size() - pos));//file.size()-pos表示pos及其之后的有效元素个数（前闭后开）//file.size()有效字符个数==最后一个元素的后一个下标
	cout << suffix << endl;//suffix后缀英文
	// 取出url中的域名
	string url("http://www.cplusplus.com/reference/string/string/find/");
	size_t start = url.find("://") + 3;//域名的开始
	size_t end = url.find('/', start) - 1;//域名最后一个下标//从://之后找
	//打印方法一：
	for (int i = start; i < end; i++)
	{
		cout << url[i];
	}
	//方法二：
	string sub = url.substr(start, end - start + 1);
	cout << sub << endl;

	// 删除url的协议前缀
	pos = url.find("://");
	url.erase(0, pos + 3);
	cout << url << endl;

}



void Test2()
{
	char c[6] = { 0 };
	string s1("abcdef");
	cout << "c_str——返回string中的字符串：" << s1.c_str() << endl;
	cout << "data——返回string中的字符串：" << s1.data() << endl;
	cout << "copy——将字符串的一部分放到字符数组：" << s1.copy(c, 5, 0) << endl;//返回拷贝的字符个数
	cout << "find——从pos之后找出字符串在string中第一次出现的位置：" << s1.find(c, 0) << endl;

	char c2[100] = "https://legacy.cplusplus.com/reference/string/string/substr/";
	cout << "c的函数strtok——找到被过滤字符分隔的一段字符串，并返回首地址：" << strtok(c2, "/") << endl;
	cout << "strtok——具有记忆功能，当第一个参数为空时，返回下一段字符串的首地址：" << strtok(NULL, "/") << endl;

	string s2("https://legacy.cplusplus.com/reference/string/string/substr/");
	cout << "c++的find_first_of——找到pos之后过滤出的第一个字符下标：" << s2.find_first_of(":/", 0) << endl;

	cout << "compare——字符串比较，全比较/从某个位置比较len长度，比较的是每个字符的ASCII码：" << s2.compare(1, 5, s1) << endl;

	//易错点
	const string& s3 = "ggg";//"ggg"才是本体
	string s4 = "hhh";

	//全局函数
	cout << "to_string：";
	int i = 111;
	//string itos = to_string(i);
	cout << to_string(i) << endl;
	cout << "stoi第二个参数是string中开始转换的位置(指针)：" << stoi("123") << endl;

	//cout << s3 << endl;
	//cout << s4 << endl;
	//cout << s2 << endl;
	//cout << s1 << endl;
	//cout << c << endl;
}

//int main()
//{
//	//Test1();
//	int arr[26] = { 0 };//初始化所有元素
//	Test2();
//
//	return 0;
//}
 






////作业
//int main(int argc, char* argv[])
//{
//	string strText = "How are you?";
//	string strSeparator = " ";
//	string strResult;
//	int size_pos = 0;
//	int size_prev_pos = 0;
//	while ((size_pos = strText.find_first_of(strSeparator, size_pos)) != string::npos)
//	{
//		cout << size_pos << endl;
//		strResult = strText.substr(size_prev_pos, size_pos - size_prev_pos);
//		cout << strResult << " ";
//		size_prev_pos = ++size_pos;
//	}
//	if (size_prev_pos != strText.size())
//	{
//		cout << size_pos << endl;
//		strResult = strText.substr(size_prev_pos, size_pos - size_prev_pos);
//		cout << strResult << " ";
//	}
//	cout << endl;
//
//	return 0;
//}


//leetcode
// 917. 仅仅反转字母
//简单
//提示
//给你一个字符串 s ，根据下述规则反转字符串：
//所有非英文字母保留在原有位置。
//所有英文字母（小写或大写）位置反转。
//返回反转后的 s 。
//class Solution {
//public:
//	string reverseOnlyLetters(string s) {
//		int i = 0, j = s.size() - 1;//最后一个有效元素下标
//		while (i < j)
//		{
//			//isalpha判断是否是字母
//			while (!isalpha(s[i]) && i < j)//在判断部分一定不能++/--，不是字母才++/--
//			{
//				i++;
//			}
//			while (!isalpha(s[j]) && i < j)
//			{
//				j--;
//			}
//			//此时都是字母
//			swap(s[i++], s[j--]);
//		}
//		return s;
//	}
//};

//leetcode
//387. 字符串中的第一个唯一字符
//简单
//给定一个字符串 s ，找到 它的第一个不重复的字符，并返回它的索引 。如果不存在，则返回 - 1 。
//示例 1：
//输入 : s = "leetcode"
//输出 : 0
//示例 2 :
//	输入 : s = "loveleetcode"
//	输出 : 2
//	示例 3 :
//	输入 : s = "aabb"
//	输出 : -1
//	提示 :
//	1 <= s.length <= 105
//	s 只包含小写字母
//class Solution {
//public:
//	int firstUniqChar(string s) {
//		//暴力解法
//		int sz = s.size();
//		//for (int i=0; i<sz && s[i]!='0'; i++)//不能这样写，这样s[i]=='0'就直接跳出循环了
//		for (int i = 0; i < sz; i++)
//		{
//			if (s[i] == '0')//说明这个位置之前是重复字符
//				continue;
//
//			//为了防止前一个重复，后一个没重复，但flag还是1的情况
//			int flag = 1;//假设没有重复的————每次都要初始化一下，
//
//			//遍历一个字符后面所有元素，查找是否有相同的，如果有就把后面重复字符改为'0'，做个标记
//			for (int j = i + 1; j < sz; j++)
//			{
//				if (s[j] == s[i])
//				{
//					s[j] = '0';
//					flag = 0;
//				}
//			}
//			if (1 == flag)//没重复的
//				return i;
//		}
//		return -1;
//	}
//};


//牛客
//HJ1 字符串最后一个单词的长度
//描述
//计算字符串最后一个单词的长度，单词以空格隔开，字符串长度小于5000。（注：字符串末尾不以空格为结尾）
//输入描述：
//输入一行，代表要计算的字符串，非空，长度小于5000。
//
//输出描述：
//输出一个整数，表示输入字符串最后一个单词的长度。
//#include <iostream>
//using namespace std;
//
//int main() {
//	//scanf()读取时会把空格作为字符串间的分隔符，每次只会读取一个单词
//
//	//cin输入的机制，有空格会停止，系统把空格作为数据间的分隔符，整个英文句子会一个单词一个单词的读。非常巧妙的使用了cin的读取逻辑
//	string s;
//	while (cin >> s);//cin >> s表达式的结果是s
//	cout << s.size();
//
//	return 0;
//}


//125. 验证回文串
//简单
//如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后，短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
//字母和数字都属于字母数字字符。
//给你一个字符串 s，如果它是 回文串 ，返回 true ；否则，返回 false 。
//示例 1：
//输入 : s = "A man, a plan, a canal: Panama"
//输出：true
//解释："amanaplanacanalpanama" 是回文串。
//class Solution {    //solution解决方案
//public:
//	bool isPalindrome(string s) {
//		//前后下标/指针比较，遇到非字母数字字符就跳过
//		int i = 0;
//		int j = s.size() - 1;
//		while (i < j)
//		{
//			//判断是否是字母数字字符
//			if (!isalnum(s[i]) && !isalnum(s[j]))//都为假——————放在前面是个小优化
//			{
//				++i;
//				--j;
//				continue;
//			}
//			else if (!isalnum(s[i]))
//			{
//				++i;
//				continue;
//			}
//			else if (isalnum(s[j]) == 0)
//			{
//				--j;
//				continue;
//			}
//
//			//判断是否是大写
//			if (isupper(s[i]))
//			{
//				s[i] += 32;//改成小写
//			}
//			if (isupper(s[j]))
//			{
//				s[j] += 32;//改成小写
//			}
//
//			if (s[i] != s[j])
//			{
//				return false;
//			}
//			else
//			{
//				++i;
//				--j;
//			}
//		}
//		return true;
//	}
//};




//leetcode
//415. 字符串相加
//简单
//给定两个字符串形式的非负整数 num1 和num2 ，计算它们的和并同样以字符串形式返回。
//你不能使用任何內建的用于处理大整数的库（比如 BigInteger）， 也不能直接将输入的字符串转换为整数形式。
//示例 1：
//输入：num1 = "11", num2 = "123"
//输出："134"

////原版：
//class Solution {
//public:
//	//思路：字符串的个/十位与个/十位相加；长的字符串加完后才结束；
//	string addStrings(string num1, string num2)
//	{
//		string str;//存放结果；
//		int end1 = num1.size() - 1;
//		int end2 = num2.size() - 1;
//		int n = 0;//每位相加之后的结果
//		int count = 0;//存放临时的进位
//		//int i = 0;//下标
//
//		//有一个还有字符就继续/全<零才结束
//		while (end1 >= 0 || end2 >= 0)
//		{
//			//方法一：
//			// if (end1>=0 && end2>=0)
//			//     n = num1[end1]-'0' + num2[end2]-'0' + count;//只有整数才能计算，所以要先转成整数 
//			// else if (end1 < 0)
//			//     n = num2[end2]-'0' + count;
//			// else //sz2<0
//			//     n = num1[end1]-'0' + count;
//
//			//方法二：
//			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;//end1往前减，<0相当于没数了，让val1一直成为0
//			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//			n = val1 + val2 + count;
//			count = n / 10;//更新进位
//			n = n % 10 + '0';//个位的字符
//			//在pos位置之前插入字符（串）
//			//insert()//头插，造成了时间复杂度O(n^2)，计算i对数据要挪动i次，复杂度是个等差数列
//			//str.insert(0, 1, n);
//			str.insert(str.begin(), n);//str.begin()是迭代器
//
//		}
//		//如果结果比两个数都长（最后的count不是0）；例如：1+9==10
//		if (count != 0)//if (count != 0)
//			str.insert(0, 1, count + '0');//
//		return str;
//	}
//};

////优化：
//class Solution {
//public:
//	//思路：字符串的个/十位与个/十位相加；长的字符串加完后才结束；
//	string addStrings(string num1, string num2)
//	{
//		string str;//存放结果；
//		//小优化：如果多次使用+=，string空间不够时会频繁开辟小空间，消耗大；
//		//可以提前就开辟足够的空间，避免+=时再开辟
//		//+1是因为可能最后还会进1，为这种情况提前做准备
//		str.reserve(num1.size() > num2.size() ? num1.size() + 1 : num2.size() + 1);
//
//		int end1 = num1.size() - 1;
//		int end2 = num2.size() - 1;
//		int n = 0;//每位相加之后的结果
//		int count = 0;//存放临时的进位
//
//		//有一个还有字符就继续/全<零才结束
//		while (end1 >= 0 || end2 >= 0)
//		{
//			int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;//end1往前减，<0相当于没数了，让val1一直成为0
//			int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//			n = val1 + val2 + count;
//			count = n / 10;//更新进位
//			n = n % 10 + '0';//个位的字符
//
//			// //原版
//			// //在pos位置之前插入字符（串）
//			// //insert()//头插，造成了时间复杂度O(n^2)，计算i对数据要挪动i次，复杂度是个等差数列
//			// //str.insert(0, 1, n);
//			// str.insert(str.begin(), n);//str.begin()是迭代器
//
//			//优化
//			//str += n;//尾插
//			str.append(1, n);
//		}
//		//如果结果比两个数都长（最后的count不是0）；例如：1+9==10
//		if (count != 0)//if (count != 0)
//			str += count + '0';//尾插；注意先转成字符
//
//		//因为是尾插，所以最后反转一下
//		reverse(str.begin(), str.end());//通用算法（通过迭代器达到通用的目的）
//
//		return str;
//	}
//};



//leetcocde
//541. 反转字符串 II
//简单
//给定一个字符串 s 和一个整数 k，从字符串开头算起，每计数至 2k 个字符，就反转这 2k 字符中的前 k 个字符。
//如果剩余字符少于 k 个，则将剩余字符全部反转。
//如果剩余字符小于 2k 但大于或等于 k 个，则反转前 k 个字符，其余字符保持原样。
//示例 1：
//输入：s = "abcdefg", k = 2
//输出："bacdfeg"
//class Solution {
//public:
//	string reverseStr(string s, int k) {
//		// int sz = s.size();
//		// for (int i=1; i<=sz; i++)//i是第几个元素，不是下标
//		// {
//		//     //每2k个元素就反转
//		//     if (i % (2*k) == 0)
//		//     {
//		//         //i-k就是最近的2k个元素中的第k个元素，下标是i-k-1
//		//         //i-2*k是最近的2k个元素中的第0个元素，就是第一个元素下标
//		//         reverse(s.begin()+(i-2*k), s.begin()+(i-k-1));//通用算法（通过迭代器翻转）
//		//         cout << s;
//		//     }
//		//     else if (s[i+1]=='\0' && i % (2*k) <= k)//s[i+1]=='\0'(说明是最后一个字符)放前面是个小优化
//		//     {
//		//         //i % (2*k)这一段的元素个数，i-i%(2*k)这一段第一个元素下标
//		//         reverse(s.begin()+(i-i%(2*k)), s.begin()+(i-1));//要提供翻转范围
//		//     }
//		//     else if (s[i+1]=='\0' && i%(2*k)>k && i%(2*k)<2*k)   //>k && <2*k
//		//     {
//		//         //i % (2*k)这一段的元素个数，i-i%(2*k)这一段第一个元素下标，+k得到第k个元素下标
//		//         reverse(s.begin()+(i-i%(2*k)), s.begin()+(i-i%(2*k)+k));
//		//     }
//		//     //其它未到最后一个字符，不满2*k的不作处理
//		// }
//		// return s;
//
//		//答案
//		int length = s.length();
//		//i是每一段的第一个位置
//		for (int i = 0; i < length; i += 2 * k)
//		{
//			// //i越界并且如果剩余字符少于 k 个，则将剩余字符全翻转
//			// //(i+2*k-1)是每段最后一个元素下标，(i+k-1)每段第k个元素下标
//			// string::iterator end = (i+2*k)>length && (i+k)>length ? s.end() : s.begin()+(i+k);//迭代器
//			// reverse(s.begin()+i, end);//reverse翻转
//
//			//min也是一个算法
//			//如果length小，说明剩余字符少于k个，将剩余字符全翻转
//			//如果i+k小，说明剩余字符小于 2k 但大于或等于 k 个，则反转前 k 个字符
//			reverse(s.begin() + i, s.begin() + min(i + k, length));//注意：reverse参数是[ )的
//		}
//		return s;
//	}
//};


//LeetCode
//557. 反转字符串中的单词 III
//简单
//给定一个字符串 s ，你需要反转字符串中每个单词的字符顺序，同时仍保留空格和单词的初始顺序。
//示例 1：
//输入：s = "Let's take LeetCode contest"
//输出："s'teL ekat edoCteeL tsetnoc"
//class Solution {
//public:
//	string reverseWords(string s) {
//		int count = 0;//计算每个单词长度
//		//for (int i=0; i<s.length(); ++i)//i一超过有效字符的界线就不会进循环了，可以让范围+1，方便判断'\0' == s[i]
//		for (int i = 0; i <= s.length(); ++i)
//		{
//			if (s[i] == ' ' || '\0' == s[i])
//			{
//				//(i-count)正好是前一个单词首字符下标
//				reverse(s.begin() + (i - count), s.begin() + i);//注意：是范围必须是前闭后开
//				count = 0;
//				continue;
//			}
//			count++;
//		}
//		return s;
//	}
//};

//LeetCode
//43. 字符串相乘
//中等
//给定两个以字符串形式表示的非负整数 num1 和 num2，返回 num1 和 num2 的乘积，它们的乘积也表示为字符串形式。
//注意：不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
//示例 1:
//输入 : num1 = "123", num2 = "456"
//输出 : "56088"
//自己暴力解法O(n^2)
//class Solution {
//public:
//    //思路：字符串的个/十位与个/十位相加；长的字符串加完后才结束；
//    string addStrings(string num1, string num2)
//    {
//        if (num1.empty())//若num1是空, 返回num2
//        {
//            return num2;
//        }
//        else if (num2.empty())//若num2是空, 返回num1
//        {
//            return num1;
//        }
//
//        string str;//存放结果；
//        //小优化：如果多次使用+=，string空间不够时会频繁开辟小空间，消耗大；
//        //可以提前就开辟足够的空间，避免+=时再开辟
//        //+1是因为可能最后还会进1，为这种情况提前做准备
//        str.reserve(num1.size() > num2.size() ? num1.size() + 1 : num2.size() + 1);
//
//        int end1 = num1.size() - 1;
//        int end2 = num2.size() - 1;
//        int n = 0;//每位相加之后的结果
//        int count = 0;//存放临时的进位
//
//        //有一个还有字符就继续/全<零才结束
//        while (end1 >= 0 || end2 >= 0)
//        {
//            int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;//end1往前减，<0相当于没数了，让val1一直成为0
//            int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//            n = val1 + val2 + count;
//            count = n / 10;//更新进位
//            n = n % 10 + '0';//个位的字符
//
//            // //原版
//            // //在pos位置之前插入字符（串）
//            // //insert()//头插，造成了时间复杂度O(n^2)，计算i对数据要挪动i次，复杂度是个等差数列
//            // //str.insert(0, 1, n);
//            // str.insert(str.begin(), n);//str.begin()是迭代器
//
//            //优化
//            //str += n;//尾插
//            str.append(1, n);
//        }
//        //如果结果比两个数都长（最后的count不是0）；例如：1+9==10
//        if (count != 0)//if (count != 0)
//            str += count + '0';//尾插；注意先转成字符
//
//        //因为是尾插，所以最后反转一下
//        reverse(str.begin(), str.end());//通用算法（通过迭代器达到通用的目的）
//
//        return str;
//    }
//
//
//    //思路：分组分开乘，再相加；例如123*456 = 123*6 + 123*50 + 123*400
//    string multiply(string num1, string num2) {
//        // size_t len1 = num1.length();
//        // size_t len2 = num2.length();
//        // size_t minlen = len1 < len2 ? len1 : len2;//当len2比len1大很多时优化明显，可以减少外循环和再相加的次数
//
//        int count = 0;//存放进位
//        int n = 0;//存放每两个数相乘的临时结果
//        string s1;//存放每组计算得到的字符串
//        string s2("0");//存放两组字符串相加的结果
//        //有一个为0, 结果就为0
//        if (num1 == "0" || num2 == "0")
//            return s2;
//
//        //num2多长就要分几组
//        for (int i = num2.length() - 1; i >= 0; --i)//从数字的低位乘到高位<-->从最右边开始乘
//        {
//            //每组计算前count要清空
//            count = 0;
//
//            //尾插效率高
//            //每一组先尾插0，因为123*400 -> 123*4 + "00" ; 尾插的0的个数==length-(下标+1)---多想想,规律
//            for (int z = num2.length() - (i + 1); z > 0; --z)
//            {
//                s1 += '0';
//            }
//
//            //一组内的每两个字符相乘
//            for (int j = num1.length() - 1; j >= 0; --j)//从数字的低位乘到高位<-->从最右边开始乘
//            {
//                //转成整数相乘
//                int n = (num2[i] - '0') * (num1[j] - '0') + count;
//                s1 += n % 10 + '0';//重新组成字符串（尾插）
//                count = n / 10;
//            }
//            //可能相乘后结果会多一位进位; 例如90*2 == 180, 多一位进位1, 这一位也要加上
//            if (count != 0)
//                s1 += count + '0';
//
//            //翻转s1
//            reverse(s1.begin(), s1.end());
//            //相加
//            string temp = addStrings(s1, s2);//string的重载=只能传 string引用 或 char*指针; addStrings返回的是局部变量的临时值
//            s2 = temp;//传引用
//            s1.clear();//清空s1为下一次存放字符串做准备
//
//        }
//        return s2;
//    }
//};



////LCR 192. 把字符串转换成整数(atoi)
//class Solution {
//public:
//	int myAtoi(string str) {
//		int res = 0;//results结果，数字拼接的结果
//		int bndry = INT_MAX / 10;//boundary边界，在边界附近检查是否越界
//		int i = 0;//遍历
//		int sign = 1;//默认是正数，sign标志，记录数字类型———正/负/无符号
//		int length = str.size();
//		//字符串为空
//		if (length == 0)
//			return 0;
//		//删除首部空格，
//		while (str[i] == ' ')
//			if (++i == length) //下一个位置==length，说明遍历结束，都是' '，返回
//				return 0;
//		//遇到'-'，sign标志修改成负数
//		if (str[i] == '-')
//			sign = -1;
//		//跳过+-符号
//		if (str[i] == '-' || str[i] == '+')
//			i++;
//		//开始正式遍历数字字符
//		for (int j = i; j < length; j++)
//		{
//			//如果又遇到非数字字符，则直接结束
//			if (str[j] < '0' || str[j] > '9')
//				break;
//
//			//如果遇到数字字符。
//			//1. 若已经读取的数字res > (bndry = 2147483647 / 10 == 214748364)，相当于res >= 214748365
//			//   则后面拼接后res一定 >= 2147483650 ，超出了正负数绝对值的范围，就没有再拼接的必要了，直接返回INT_MAX或INT_MIN
//			//2. 若已经读取的数字res == 214748364 ，
//			//      并且下一个是大于7的数字字符（要么是2147483648 INT_MIN的绝对值，要么越界） 
//			//      或 字母字符（字母字符的ASCII大于'7'的）——————错了，前面已经判断了，当前的str[j]一定是数字字符
//			if (res > bndry || res == bndry && str[j] > '7')
//				return sign == 1 ? INT_MAX : INT_MIN;
//
//			//已经读取的数字*10 与 当前数字相加 拼接 == 得到的就是现在读取到的数字
//			res = res * 10 + (str[j] - '0');
//		}
//		return sign * res;
//	}
//};



////387. 字符串中的第一个唯一字符
//class Solution
//{
//public:
//	int firstUniqChar(string s) //unique唯一/独特/独一无二
//	{
//		//借助计数排序的思想
//		//记录每个字符个数，zuu并根据字符范围绝对/相对映射，将个数放进新数组的对应下标上
//		//范围是26个小写字母，字符的ASCII码与0相差大，用相对映射
//		int arr[26] = { 0 };//初始化每个元素
//		// for (int j=0; j<s.size(); ++j)
//		// {
//		//     arr[s[j] - 'a']++;//在字符映射的位置上存放累计字符个数；字符相对与'a'的距离就是下标
//		// }
//		for (auto ch : s)//ch就是s里的每个元素的一份拷贝
//		{
//			arr[ch - 'a']++;
//		}
//
//		//遍历原字符串，第一个不重复的字符
//		for (int j = 0; j < s.size(); ++j)
//		{
//			//找到第一个不重复的字符————错误，注意：要求的是找到原字符串中的
//			if (arr[s[j] - 'a'] == 1)//(s[j] - '0')是字符映射的下标，找到第一个映射的位置上是1的，返回字符下标
//			{
//				return j;
//			}
//		}
//		//不存在
//		return -1;
//	}
//};

//int main()
//{
//	Solution s;
//	cout << s.firstUniqChar("loveleetcode") << endl;
//
//	return 0;
//}